package com.example.frame;

import android.content.Context;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * 作者: Andy
 * 时间: 2017-06-13
 * 描述:
 * 间距可以做成属性外部配置
 * 暂时写成常量
 */
public class ImageFrame extends ViewGroup {

    /**
     * 横向间距
     */
    private int mHorzontalSpacing = 10;

    /**
     * 纵向间距
     */
    private int mVerticalSpacing = 10;

    /**
     * 回调刷新数据
     */
    private ImageDataObsever mImageDataObsever;

    /**
     * 适配器
     */
    private AbsFrameAdapter mFrameAdapter;

    /**
     * 子类数量
     */
    private int mChildCount;

    public ImageFrame(Context context) {
        super(context);
    }

    public ImageFrame(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ImageFrame(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mFrameAdapter != null && mImageDataObsever != null) {
            mFrameAdapter.unregisterDataSetObserver(mImageDataObsever);
            mImageDataObsever = null;
        }
    }

    public void setAdapter(AbsFrameAdapter adapter) {
        if (adapter == null)
            return;
        if (mFrameAdapter != adapter) {
            mFrameAdapter = adapter;
            mImageDataObsever = new ImageDataObsever();
            mFrameAdapter.registerDataSetObserver(mImageDataObsever);
        }
        updateItems();
    }

    private void updateItems() {
        if (mFrameAdapter != null) {
            mChildCount = Math.min(9, mFrameAdapter.getCount());
            final int maxChild = Math.min(5, mChildCount);
            removeAllViews();
            for (int i = 0; i < maxChild; i++) {
                View child = mFrameAdapter.getView(i, null, this);
                addView(child);
            }
        }
    }

    private class ImageDataObsever extends DataSetObserver {
        @Override
        public void onChanged() {
            super.onChanged();
            updateItems();
        }

        @Override
        public void onInvalidated() {
            super.onInvalidated();
            updateItems();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int paddingLeft = getPaddingLeft();
        final int paddingRight = getPaddingRight();
        final int paddingTop = getPaddingTop();
        final int paddingBottom = getPaddingBottom();
        switch (mChildCount) {
            case 1:
                measureOne(width, paddingLeft, paddingTop, paddingRight, paddingBottom);
                break;
            case 2:
                measureTwo(width, paddingLeft, paddingTop, paddingRight, paddingBottom);
                break;
            case 3:
                measureThree(width, paddingLeft, paddingTop, paddingRight, paddingBottom);
                break;
            case 4:
                measureFour(width, paddingLeft, paddingTop, paddingRight, paddingBottom);
                break;
            case 5:
            case 6:
            case 7:
            case 8:
                measureFive(width, paddingLeft, paddingTop, paddingRight, paddingBottom);
                break;
            case 9:
                measureLast(width, paddingLeft, paddingTop, paddingRight, paddingBottom);
                break;
        }
        //测量父容器
        setMeasuredDimension(width, width);
    }

    /**
     * 测量第一种类型
     *
     * @param width
     * @param paddingLeft
     * @param paddingTop
     * @param paddingRight
     * @param paddingBottom
     */
    private void measureOne(int width, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
        View child = getChildAt(0);
        final int widthMeasure = MeasureSpec.makeMeasureSpec(width - paddingLeft - paddingRight, MeasureSpec.EXACTLY);
        final int heightMeasure = MeasureSpec.makeMeasureSpec(width - paddingTop - paddingBottom, MeasureSpec.EXACTLY);
        child.measure(widthMeasure, heightMeasure);
    }

    /**
     * 测量第二种类型
     *
     * @param width
     * @param paddingLeft
     * @param paddingTop
     * @param paddingRight
     * @param paddingBottom
     */
    private void measureTwo(int width, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
        final int widthMeasure = MeasureSpec.makeMeasureSpec((width - paddingLeft - paddingRight - mHorzontalSpacing) / 2, MeasureSpec.EXACTLY);
        final int heightMeasure = MeasureSpec.makeMeasureSpec((width - paddingTop - paddingBottom), MeasureSpec.EXACTLY);
        for (int i = 0; i < 2; i++) {
            View child = getChildAt(i);
            child.measure(widthMeasure, heightMeasure);
        }
    }

    /**
     * 测量第三种类型
     *
     * @param width
     * @param paddingLeft
     * @param paddingTop
     * @param paddingRight
     * @param paddingBottom
     */
    private void measureThree(int width, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
        final int topWidth = width - paddingLeft - paddingRight;
        final int topHeight = width - paddingTop - paddingBottom;
        final int topWidthMeasure = MeasureSpec.makeMeasureSpec(topWidth, MeasureSpec.EXACTLY);
        final int topHeightMeasure = MeasureSpec.makeMeasureSpec((topHeight - mVerticalSpacing) / 2, MeasureSpec.EXACTLY);
        final int bottomWidthMeasure = MeasureSpec.makeMeasureSpec((topWidth - mHorzontalSpacing) / 2, MeasureSpec.EXACTLY);
        View topView = getChildAt(0);
        topView.measure(topWidthMeasure, topHeightMeasure);
        for (int i = 0; i < 2; i++) {
            View child = getChildAt(i + 1);
            child.measure(bottomWidthMeasure, topHeightMeasure);
        }

    }

    /**
     * 测量第四种类型
     *
     * @param width
     * @param paddingLeft
     * @param paddingTop
     * @param paddingRight
     * @param paddingBottom
     */
    private void measureFour(int width, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
        final int topWidth = width - paddingLeft - paddingRight;
        final int topHeight = width - paddingTop - paddingBottom;
        final int topWidthMeasure = MeasureSpec.makeMeasureSpec(topWidth, MeasureSpec.EXACTLY);
        final int itemWidth = (topWidth - mHorzontalSpacing * 2) / 3;
        final int bottomMeasure = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
        final int topHeightMeasure = MeasureSpec.makeMeasureSpec(topHeight - mVerticalSpacing - itemWidth, MeasureSpec.EXACTLY);
        View topView = getChildAt(0);
        topView.measure(topWidthMeasure, topHeightMeasure);
        for (int i = 0; i < 3; i++) {
            View child = getChildAt(i + 1);
            child.measure(bottomMeasure, bottomMeasure);
        }
    }

    /**
     * 测量第五种类型
     *
     * @param width
     * @param paddingLeft
     * @param paddingTop
     * @param paddingRight
     * @param paddingBottom
     */
    private void measureFive(int width, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
        final int topWidth = width - paddingLeft - paddingRight;
        final int topHeight = width - paddingTop - paddingBottom;
        final int topWidthMeasure = MeasureSpec.makeMeasureSpec((topWidth - mHorzontalSpacing) / 2, MeasureSpec.EXACTLY);
        final int itemWidth = (topWidth - mHorzontalSpacing * 2) / 3;
        final int bottomMeasure = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
        final int topHeightMeasure = MeasureSpec.makeMeasureSpec(topHeight - mVerticalSpacing - itemWidth, MeasureSpec.EXACTLY);
        //测量前两个元素
        for (int i = 0; i < 2; i++) {
            View child = getChildAt(i);
            child.measure(topWidthMeasure, topHeightMeasure);
        }
        //测量后三个元素
        for (int i = 2; i < 5; i++) {
            View child = getChildAt(i);
            child.measure(bottomMeasure, bottomMeasure);
        }
    }

    /**
     * 测量第五种类型
     *
     * @param width
     * @param paddingLeft
     * @param paddingTop
     * @param paddingRight
     * @param paddingBottom
     */
    private void measureLast(int width, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
        final int topWidth = width - paddingLeft - paddingRight;
        final int topHeight = width - paddingTop - paddingBottom;
        final int itemWidth = (topWidth - mVerticalSpacing * 2) / 3;
        final int bottomMeasure = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
        final int topWidthMeasure = MeasureSpec.makeMeasureSpec(topWidth - mHorzontalSpacing - itemWidth, MeasureSpec.EXACTLY);
        final int topHeightMeasure = MeasureSpec.makeMeasureSpec((topHeight - mVerticalSpacing) / 2, MeasureSpec.EXACTLY);
        //测量前两个元素
        for (int i = 0; i < 2; i++) {
            View child = getChildAt(i);
            child.measure(topWidthMeasure, topHeightMeasure);
        }
        //测量后三个元素
        for (int i = 2; i < 5; i++) {
            View child = getChildAt(i);
            child.measure(bottomMeasure, bottomMeasure);
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        switch (mChildCount) {
            case 1:
                oneShow(left, top);
                break;
            case 2:
                twoShow(left, top);
                break;
            case 3:
                threeShow(left, top);
                break;
            case 4:
                fourShow(left, top);
                break;
            case 5:
            case 6:
            case 7:
            case 8:
                fiveShow(left, top);
                break;
            case 9:
                lastShow(left, top);
                break;
        }

    }

    /**
     * 显示一张图片
     *
     * @param left
     * @param top
     */
    private void oneShow(int left, int top) {
        View child = getChildAt(0);
        final int width = child.getMeasuredWidth();
        final int height = child.getMeasuredHeight();
        final int paddingLeft = getPaddingLeft();
        final int paddingTop = getPaddingTop();
        child.layout(left + paddingLeft, top + paddingTop, left + paddingLeft + width, top + height + paddingTop);
    }

    /**
     * 显示两张图片
     *
     * @param left
     * @param top
     */
    private void twoShow(int left, int top) {
        for (int i = 0; i < 2; i++) {
            View child = getChildAt(i);
            final int width = child.getMeasuredWidth();
            final int height = child.getMeasuredHeight();
            final int paddingLeft = getPaddingLeft();
            final int paddingTop = getPaddingTop();
            child.layout(left + i * width + paddingLeft + mHorzontalSpacing * i, top + paddingTop, left + width * (i + 1) + paddingLeft + mHorzontalSpacing * i, top + height + paddingTop);
        }
    }


    /**
     * 三张图片显示
     *
     * @param left
     * @param top
     */
    private void threeShow(int left, int top) {
        View topView = getChildAt(0);
        final int topWidth = topView.getMeasuredWidth();
        final int topHeight = topView.getMeasuredHeight();
        final int paddingLeft = getPaddingLeft();
        final int paddingTop = getPaddingTop();
        topView.layout(left + paddingLeft, top + paddingTop, left + topWidth + paddingLeft, top + topHeight + paddingTop);
        //布局下面两个
        for (int i = 0; i < 2; i++) {
            View child = getChildAt(i + 1);
            final int width = child.getMeasuredWidth();
            final int height = child.getMeasuredHeight();
            child.layout(left + i * width + paddingLeft + mHorzontalSpacing * i, top + topHeight + paddingTop + mVerticalSpacing, left + width * (i + 1) + paddingLeft + mHorzontalSpacing * i, top + topHeight + height + paddingTop + mVerticalSpacing);
        }
    }

    /**
     * 四张图片显示
     *
     * @param left
     * @param top
     */
    private void fourShow(int left, int top) {
        View topView = getChildAt(0);
        final int topWidth = topView.getMeasuredWidth();
        final int topHeight = topView.getMeasuredHeight();
        final int paddingLeft = getPaddingLeft();
        final int paddingTop = getPaddingTop();
        topView.layout(left + paddingLeft, top + paddingTop, left + topWidth + paddingLeft, top + topHeight + paddingTop);
        //布局下面两个
        for (int i = 0; i < 3; i++) {
            View child = getChildAt(i + 1);
            final int width = child.getMeasuredWidth();
            final int height = child.getMeasuredHeight();
            child.layout(left + i * width + paddingLeft + mHorzontalSpacing * i, top + paddingTop + topHeight + mVerticalSpacing, left + width * (i + 1) + paddingLeft + mHorzontalSpacing * i, top + topHeight + height + paddingTop + mVerticalSpacing);
        }
    }

    /**
     * 五张图片显示
     *
     * @param left
     * @param top
     */
    private void fiveShow(int left, int top) {
        final int paddingLeft = getPaddingLeft();
        final int paddingTop = getPaddingTop();
        //布局前两个元素
        int topHeight = 0;
        for (int i = 0; i < 2; i++) {
            View topView = getChildAt(i);
            final int topWidth = topView.getMeasuredWidth();
            topHeight = topView.getMeasuredHeight();
            topView.layout(left + paddingLeft + i * topWidth + mHorzontalSpacing * i, top + paddingTop, left + topWidth * (i + 1) + paddingLeft + mHorzontalSpacing * i, top + paddingTop + topHeight);
        }
        //布局后面三个元素
        for (int i = 0; i < 3; i++) {
            View child = getChildAt(i + 2);
            final int bottomWidth = child.getMeasuredWidth();
            final int bottomHeight = child.getMeasuredHeight();
            child.layout(left + paddingLeft + i * bottomWidth + mHorzontalSpacing * i, top + paddingTop + topHeight + mVerticalSpacing, left + bottomWidth * (i + 1) + paddingLeft + mHorzontalSpacing * i, top + paddingTop + topHeight + bottomHeight + mVerticalSpacing);
        }
    }

    /**
     * 最后一种形式图片显示
     * 五张图片
     *
     * @param left
     * @param top
     */
    private void lastShow(int left, int top) {
        final int paddingLeft = getPaddingLeft();
        final int paddingTop = getPaddingTop();
        //布局前两个元素
        int topWidth = 0;
        for (int i = 0; i < 2; i++) {
            View leftView = getChildAt(i);
            topWidth = leftView.getMeasuredWidth();
            final int topHeight = leftView.getMeasuredHeight();
            leftView.layout(left + paddingLeft, top + paddingTop + topHeight * i + mVerticalSpacing * i, left + paddingLeft + topWidth, top + paddingTop + topHeight * (i + 1) + mVerticalSpacing * i);
        }
        //布局后面三个元素
        for (int i = 0; i < 3; i++) {
            View child = getChildAt(i + 2);
            final int bottomWidth = child.getMeasuredWidth();
            final int bottomHeight = child.getMeasuredHeight();
            child.layout(left + paddingLeft + topWidth + mHorzontalSpacing, top + paddingTop + bottomHeight * i + mVerticalSpacing * i, left + paddingLeft + topWidth + mHorzontalSpacing + bottomWidth, top + paddingTop + bottomHeight * (i + 1) + mVerticalSpacing * i);
        }
    }
}
